using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using RebelStar.Engine;
using RebelStar.Engine.Graphics.MDX;
using ButtonState=Microsoft.Xna.Framework.Input.ButtonState;
using Keys=Microsoft.Xna.Framework.Input.Keys;

namespace RebelStar
{
    public class Game : Microsoft.Xna.Framework.Game
    {
        const int scrollSens = 10;

        GameBase gameBase;
        MouseState oldState;
        KeyboardState oldKeyState;

        NetworkSession networkSession;
        AvailableNetworkSessionCollection availableSessions;
        PacketReader packetReader = new PacketReader();
        PacketWriter packetWriter = new PacketWriter();

        public Game()
        {
            new GraphicsDeviceManager(this);
            Components.Add(new GamerServicesComponent(this));
            SignedInGamer.SignedIn += SignedInGamer_SignedIn;
        }

        protected override void Initialize()
        {
            gameBase = new GameBase(new XNAGraphicsDevice(this));

            base.IsMouseVisible = true;

            try
            {
                base.Initialize();
            }
            catch (GamerServicesNotAvailableException)
            {
                MessageBox.Show("Another instance of the LIVE game is executed");
                Application.Exit();
            }
        }
        protected override void LoadContent()
        {
            gameBase.Initialize();
            gameBase.LoadMap();
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            updateKeyboard();
            updateMouse();

            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            gameBase.ReDraw();

            base.Draw(gameTime);
        }

        void updateMouse()
        {
            MouseState state = Mouse.GetState();

            gameBase.SetCursor(state.X, state.Y);
            
            if (state.LeftButton == ButtonState.Pressed && oldState.LeftButton != ButtonState.Pressed)
                gameBase.StartSelection(gameBase.Cursor.X, gameBase.Cursor.Y);
            if (state.LeftButton != ButtonState.Pressed && oldState.LeftButton == ButtonState.Pressed)
                gameBase.EndSelection(gameBase.Cursor.X, gameBase.Cursor.Y);

            if (state.RightButton != ButtonState.Pressed && oldState.RightButton == ButtonState.Pressed)
                gameBase.ResetSelection();

            if (state.MiddleButton == ButtonState.Pressed)
                gameBase.Scroll((state.X - oldState.X)/scrollSens, (state.Y - oldState.Y)/scrollSens);

            if (state.ScrollWheelValue != oldState.ScrollWheelValue)
            {
                float scale = gameBase.Scale;
                scale += 0.1f * (state.ScrollWheelValue - oldState.ScrollWheelValue) / 120;
                if (scale > 1) scale = 1f;
                if (scale < 0.1f) scale = 0.1f;
                gameBase.SetScale(scale);
            }

            oldState = state;
        }
        void updateKeyboard()
        {
            KeyboardState keyState = Keyboard.GetState();

            if (isKeyPressed(keyState, oldKeyState, Keys.C))
            {
                networkSession = NetworkSession.Create(
                    NetworkSessionType.SystemLink,
                    1, 8, 2,
                    null);
                networkSession.AllowHostMigration = true;
                networkSession.AllowJoinInProgress = true;

                networkSession.GamerJoined += networkSession_GamerJoined;
            }
            if (isKeyPressed(keyState, oldKeyState, Keys.F))
            {
                availableSessions = NetworkSession.Find(
                    NetworkSessionType.SystemLink, 1, null);

                if (availableSessions.Count > 0)
                {
                    networkSession = NetworkSession.Join(availableSessions[0]);

                    availableSessions.Dispose();
                    availableSessions = null;

                    networkSession.GamerJoined += networkSession_GamerJoined;
                }
            }
            
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad1))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad1);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad2) ||
                isKeyPressed(keyState, oldKeyState, Keys.Down))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad2);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad3))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad3);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad4) ||
                isKeyPressed(keyState, oldKeyState, Keys.Left))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad4);
//            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad5))
//                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad5);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad6) ||
                isKeyPressed(keyState, oldKeyState, Keys.Right))
                    gameBase.KeyPress(System.Windows.Forms.Keys.NumPad6);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad7))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad7);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad8) ||
                isKeyPressed(keyState, oldKeyState, Keys.Up))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad8);
            if (isKeyPressed(keyState, oldKeyState, Keys.NumPad9))
                gameBase.KeyPress(System.Windows.Forms.Keys.NumPad9);

            oldKeyState = keyState;
        }
        bool isKeyPressed(KeyboardState newState, KeyboardState oldState, Keys key)
        {
            return newState.IsKeyDown(key) && !oldState.IsKeyDown(key);
        }

        void SignedInGamer_SignedIn(object sender, SignedInEventArgs e)
        {
            gameBase.AddPlayer(e.Gamer);
        }
        void networkSession_GamerJoined(object sender, GamerJoinedEventArgs e)
        {
            if (!e.Gamer.IsLocal)
            {
                gameBase.AddPlayer(e.Gamer);
            }
            else
            {
            }
        }
    }
}
